package ru.nsu.fit.conveyor.conveyorgenerator;

import demo.*;
import ru.nsu.fit.iconveyor.conveyor.Conveyor;
import ru.nsu.fit.iconveyor.conveyor.storage.exporter.Exporter;
import ru.nsu.fit.iconveyor.conveyor.storage.exporter.graphml.GraphMLExporter;
import ru.nsu.fit.iconveyor.engine.ConveyorExecutionObserver;
import ru.nsu.fit.iconveyor.engine.Engine;
import ru.nsu.fit.iconveyor.engine.smart.SmartEngine;
import ru.nsu.fit.iconveyor.log.console.ConsoleLoggingEngineStateObserver;

import java.util.Collection;
import java.util.Properties;

public class Launcher {

    public static void main(String [] args) {

        if(args.length < 1) {
            System.err.println("no name of output file specified");
            return;
        }
        final String outputFileName = args[0];

        if(args.length < 2) {
            System.err.println("no name of jar file with node classes specified");
            return;
        }
        final String jarFileName = args[1];


        Properties prop = new Properties();

        Conveyor conveyor = new Conveyor();
        conveyor.setProperties(prop);

        InputPictureNode inputPicture = new InputPictureNode("Input");
        //inputPicture.setParameter(InputPictureNode.INPUT_FILE_NAMES, "examples/lena.bmp");
        inputPicture.setParameter(InputPictureNode.INPUT_FILE_NAMES, "examples/lena.bmp|examples/jolie.bmp");


        FileNameDelimiterNode fileNameDelimiterNode = new FileNameDelimiterNode("FileNameDelimiterNode");
        ImageReaderNode imageReaderNode = new ImageReaderNode("ImageReaderNode");
        SplitNode splitNode = new SplitNode("SplitNode");
        ToBlackAndWhiteNode toBlackAndWhiteNode = new ToBlackAndWhiteNode("ToBlackAndWhiteNode");
        BlurNode blurNode = new BlurNode("BlurNode");
        ReduceNode reduceNode = new ReduceNode("ReduceNode");
        ImageWriterNode imageWriterNode = new ImageWriterNode("ImageWriterNode");

        splitNode.setParameter(SplitNode.SPLIT_COLUMN_COUNT_PARAMETER, "10");
        splitNode.setParameter(SplitNode.SPLIT_ROW_COUNT_PARAMETER, "10");
        reduceNode.setParameter(ReduceNode.SPLIT_COLUMN_COUNT_PARAMETER, "10");
        reduceNode.setParameter(ReduceNode.SPLIT_ROW_COUNT_PARAMETER, "10");
        imageWriterNode.setParameter(ImageWriterNode.PARAM_OUTPUT_FOLDER_PATH, "examples/out/");

        // create channel From_Input_2_FileNameDelimiterNode
        {
            String channelId  = "From_Input_2_FileNameDelimiterNode";
            inputPicture.getOutputNodeConnectionByName(InputPictureNode.OUTPUT_RESULT).setChannelId(channelId);
            fileNameDelimiterNode.getInputNodeConnectionByName(FileNameDelimiterNode.INPUT_ARG).setChannelId(channelId);
            conveyor.addChannelId(channelId);
        }

        // create channel From_FileNameDelimiterNode_2_FileNameDelimiterNode
        {
            String channelId  = "From_FileNameDelimiterNode_2_FileNameDelimiterNode";
            fileNameDelimiterNode.getOutputNodeConnectionByName(FileNameDelimiterNode.OUTPUT_ARG_LOOP).setChannelId(channelId);
            fileNameDelimiterNode.getInputNodeConnectionByName(FileNameDelimiterNode.INPUT_ARG_LOOP).setChannelId(channelId);
            conveyor.addChannelId(channelId);
        }

        // create channel From_FileNameDelimiterNode_2_ImageReaderNode
        {
            String channelId  = "From_FileNameDelimiterNode_2_ImageReaderNode";
            fileNameDelimiterNode.getOutputNodeConnectionByName(FileNameDelimiterNode.OUTPUT_RESULT).setChannelId(channelId);
            imageReaderNode.getInputNodeConnectionByName(ImageReaderNode.INPUT_ARG).setChannelId(channelId);
            conveyor.addChannelId(channelId);
        }

        // create channel From_FileNameDelimiterNode_2_SplitNode
        {
            String channelId  = "From_ImageReaderNode_2_SplitNode";
            imageReaderNode.getOutputNodeConnectionByName(ImageReaderNode.OUTPUT_RESULT).setChannelId(channelId);
            splitNode.getInputNodeConnectionByName(SplitNode.INPUT_ARG).setChannelId(channelId);
            conveyor.addChannelId(channelId);
        }

        // create channel From_SplitNode_2_SplitNode
        {
            String channelId  = "From_SplitNode_2_SplitNode";
            splitNode.getOutputNodeConnectionByName(SplitNode.OUTPUT_ARG_LOOP).setChannelId(channelId);
            splitNode.getInputNodeConnectionByName(SplitNode.INPUT_ARG_LOOP).setChannelId(channelId);
            conveyor.addChannelId(channelId);
        }

        // create channel From_SplitNode_2_ToBlackAndWhiteNode
        {
            String channelId  = "From_SplitNode_2_ToBlackAndWhiteNode";
            splitNode.getOutputNodeConnectionByName(SplitNode.OUTPUT_RESULT).setChannelId(channelId);
            toBlackAndWhiteNode.getInputNodeConnectionByName(ToBlackAndWhiteNode.INPUT_IMAGE).setChannelId(channelId);
            conveyor.addChannelId(channelId);
        }

        // create channel From_ToBlackAndWhiteNode_2_BlurNode
        {
            String channelId  = "From_ToBlackAndWhiteNode_2_BlurNode";
            toBlackAndWhiteNode.getOutputNodeConnectionByName(ToBlackAndWhiteNode.OUTPUT_IMAGE).setChannelId(channelId);
            blurNode.getInputNodeConnectionByName(BlurNode.INPUT_IMAGE).setChannelId(channelId);
            conveyor.addChannelId(channelId);
        }

        // create channel From_BlurNode_2_ReduceNode
        {
            String channelId  = "From_BlurNode_2_ReduceNode";
            blurNode.getOutputNodeConnectionByName(BlurNode.OUTPUT_IMAGE).setChannelId(channelId);
            reduceNode.getInputNodeConnectionByName(ReduceNode.INPUT_ARG).setChannelId(channelId);
            conveyor.addChannelId(channelId);
        }

        // create channel From_ReduceNode_2_ReduceNode
        {
            String channelId  = "From_ReduceNode_2_ReduceNode";
            reduceNode.getOutputNodeConnectionByName(ReduceNode.OUTPUT_ARG_LOOP).setChannelId(channelId);
            reduceNode.getInputNodeConnectionByName(ReduceNode.INPUT_ARG_LOOP).setChannelId(channelId);
            conveyor.addChannelId(channelId);
        }

        // create channel From_ReduceNode_2_ImageWriterNode
        {
            String channelId  = "From_ReduceNode_2_ImageWriterNode";
            reduceNode.getOutputNodeConnectionByName(ReduceNode.OUTPUT_RESULT).setChannelId(channelId);
            imageWriterNode.getInputNodeConnectionByName(ImageWriterNode.INPUT_IMAGE).setChannelId(channelId);
            conveyor.addChannelId(channelId);
        }

        conveyor.addNodes(inputPicture,
                fileNameDelimiterNode,
                imageReaderNode,
                splitNode,
                toBlackAndWhiteNode,
                blurNode,
                reduceNode,
                imageWriterNode);


        System.err.println("Start export...");
        try {
            Exporter.exportToFile(outputFileName, conveyor, jarFileName);
        } catch (Exception e) {
            System.err.println("error of exporting conveyor: " + e.getLocalizedMessage());
        }

        System.err.println("Export finished");

    }

}
